package cn.easyplatform.studio.utils;

import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.vos.TemplateVo;
import org.dom4j.Element;
import org.zkoss.util.resource.Labels;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class TemplateUtil {
    public enum TemplateType {
        TEMPLATE_TYPE_DESKTOP_LOGIN("Desktop-login"),
        TEMPLATE_TYPE_DESKTOP_MAIN("Desktop-main"),
        TEMPLATE_TYPE_MOBILE_LOGIN("Mobile-login"),
        TEMPLATE_TYPE_MOBILE_MAIN("Mobile-main");

        String name;

        private TemplateType(String name) {
            this.name = name;
        }

        public String getName() {
            return this.name;
        }

        public String toString() {
            return this.name;
        }
    }

    private  String projectName = Contexts.getProject().getId();

    private  String desktopLoginFile = "/WEB-INF/template/" + projectName + "/d0";

    private  String desktopLoginHisFile = "/WEB-INF/template/" + projectName + "/his/d0";

    private  String desktopMainFile = "/WEB-INF/template/" + projectName + "/d1";

    private  String desktopMainHisFile = "/WEB-INF/template/" + projectName + "/his/d1";

    private  String mobileLoginFile = "/WEB-INF/template/" + projectName + "/m0";

    private  String mobileLoginHisFile = "/WEB-INF/template/" + projectName + "/his/m0";

    private  String mobileMainFile = "/WEB-INF/template/" + projectName + "/m1";

    private  String mobileMainHisFile = "/WEB-INF/template/" + projectName + "/his/m1";

    private List<TemplateVo> publicTemplateVos;

    public List<TemplateVo> getTemplateWithType(TemplateType type) {
        publicTemplateVos = getTemplate();
        List<TemplateVo> templateVos = new ArrayList<>();
        for (TemplateVo templateVo: publicTemplateVos) {
            if (templateVo.getProductType().getName().equals(type.getName()))
                templateVos.add(templateVo);
        }
        return templateVos;
    }

    public List<TemplateVo> getTemplate() {
        List<TemplateVo> templateVos = new ArrayList<>();
        File file = new File(StudioApp.getServletContext().getRealPath("/WEB-INF/lib/template/"));
        if (file.exists()) {
            String[] fileNameList = file.list();
            for (String fileName: fileNameList) {
                File templateFile = new File(StudioApp.getServletContext().getRealPath("/WEB-INF/lib/template/" + fileName));
                if (templateFile.isFile() && fileName.endsWith(".jar")) {
                    Properties prop = FileUtil.getJarMFWithFileName(templateFile.getPath());
                    TemplateVo templateVo = new TemplateVo();
                    templateVo.setProductIdentifier(fileName);
                    templateVo.setProductDisplayName(prop.getProperty("Template-Title"));
                    templateVo.setProductType(typeString(prop.getProperty("Template-Type")));
                    ArrayList<String> list = new ArrayList<>();
                    list.add(prop.getProperty("Template-Snapshot"));
                    templateVo.setProductPreview(list);
                    ArrayList<String> zulList = new ArrayList<>();
                    zulList.add(prop.getProperty("Template-File"));
                    templateVo.setZULFiles(zulList);
                    templateVos.add(templateVo);
                }
            }
        }
        return templateVos;
    }

    public TemplateVo getTemplateVo(String pathName,TemplateType type) {
        String fileStr = StudioApp.getServletContext().getRealPath(getFilePath(pathName,type) + "/META-INF/MANIFEST.MF");
        if (!new File(fileStr).exists()) {
            WebUtils.showError(Labels.getLabel("editor.template.error.choose"));
            return null;
        }
        Properties prop = new Properties();
        try {
            prop.load(new InputStreamReader(new FileInputStream(fileStr),"utf-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        TemplateVo templateVo = new TemplateVo();
        templateVo.setProductDisplayName(prop.getProperty("Template-Title"));
        templateVo.setProductType(typeString(prop.getProperty("Template-Type")));
        ArrayList<String> list = new ArrayList<>();
        list.add(prop.getProperty("Template-File"));
        templateVo.setZULFiles(list);
        return templateVo;
    }

    public TemplateType typeString(String typeString) {
        if (TemplateType.TEMPLATE_TYPE_DESKTOP_LOGIN.getName().equals(typeString))
            return TemplateType.TEMPLATE_TYPE_DESKTOP_LOGIN;
        else if (TemplateType.TEMPLATE_TYPE_DESKTOP_MAIN.getName().equals(typeString))
            return TemplateType.TEMPLATE_TYPE_DESKTOP_MAIN;
        else if (TemplateType.TEMPLATE_TYPE_MOBILE_LOGIN.getName().equals(typeString))
            return TemplateType.TEMPLATE_TYPE_MOBILE_LOGIN;
        else if (TemplateType.TEMPLATE_TYPE_MOBILE_MAIN.getName().equals(typeString))
            return TemplateType.TEMPLATE_TYPE_MOBILE_MAIN;
        else
            throw new RuntimeException("error.type");
    }

    public void copyTemplate(String pathName,String templateVoID, TemplateType templateType) {
        String path = new AppServiceFileUtils().getFilePath(pathName,templateType);
        String hisPath = new AppServiceFileUtils().getHisFilePath(pathName,templateType);
        File file = new File(path);
        FileUtil.delAllFile(hisPath);
        if((file.isDirectory() && file.list().length > 0)){
            try {
                FileUtil.copyDir(path, hisPath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        FileUtil.delAllFile(path);
        File templateFile = new File(new AppServiceFileUtils().getJarFilePath()+ "/" +templateVoID);
        ZipUtil.unJarZip(templateFile, path);
    }

    public String getFilePath(String pathName,TemplateType templateType) {
        String path = null;
        if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_DESKTOP_LOGIN.getName()))
            path = desktopLoginFile+pathName;
        else if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_DESKTOP_MAIN.getName()))
            path = desktopMainFile+pathName;
        else if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_MOBILE_LOGIN.getName()))
            path = mobileLoginFile+pathName;
        else if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_MOBILE_MAIN.getName()))
            path = mobileMainFile+pathName;
        FileUtil.mkdirForNoExists(StudioApp.getServletContext().getRealPath(path));
        return path;
    }

    public String getHisFilePath(String pathName,TemplateType templateType) {
        String path = null;
        if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_DESKTOP_LOGIN.getName()))
            path = desktopLoginHisFile+pathName;
        else if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_DESKTOP_MAIN.getName()))
            path = desktopMainHisFile+pathName;
        else if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_MOBILE_LOGIN.getName()))
            path = mobileLoginHisFile+pathName;
        else if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_MOBILE_MAIN.getName()))
            path = mobileMainHisFile+pathName;
        FileUtil.mkdirForNoExists(StudioApp.getServletContext().getRealPath(path));
        return path;
    }

    public String getCoreFilePath (TemplateType templateType) {
        String path = null;
        if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_DESKTOP_LOGIN.getName()))
            path = desktopLoginFile;
        else if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_DESKTOP_MAIN.getName()))
            path = desktopMainFile;
        else if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_MOBILE_LOGIN.getName()))
            path = mobileLoginFile;
        else if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_MOBILE_MAIN.getName()))
            path = mobileMainFile;
        FileUtil.mkdirForNoExists(StudioApp.getServletContext().getRealPath(path));
        return path;
    }

    public boolean templateIsLegal(String templatePath, TemplateType type) {
        String realPath = StudioApp.getServletContext().getRealPath(templatePath + "/META-INF/MANIFEST.MF");
        if (!new File(realPath).exists()) {
            return false;
        }
        Properties prop = new Properties();
        try {
            prop.load(new InputStreamReader(new FileInputStream(realPath),"utf-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (type.getName().equals(prop.getProperty("Template-Type")))
            return true;
        else
            return false;
    }

    private Element searchElement(String value, List<Element> allElements) {
        Element nextElement = null;
        for (int index = 0; index < allElements.size(); index++) {
            Element allElement = allElements.get(index);
            if (allElement.getStringValue().equals(value)) {
                nextElement = allElements.get(index + 1);
                break;
            }
        }
        return nextElement;
    }

    public void copyTemplateBackups (String templateVoID, TemplateType templateType) {
        String path = StudioApp.getServletContext().getRealPath(getCoreFilePath(templateType));
        String hisPath = StudioApp.getServletContext().getRealPath(getHisFilePathBackups(templateType));
        try {
            FileUtil.copyDir(path, hisPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        FileUtil.delAllFile(path);
        File templateFile = new File(StudioApp.getServletContext().getRealPath("/WEB-INF/lib/template/" + templateVoID));
        ZipUtil.unJarZip(templateFile, path);
    }

    public String getHisFilePathBackups (TemplateType templateType) {
        String path = null;
        if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_DESKTOP_LOGIN.getName()))
            path = desktopLoginHisFile;
        else if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_DESKTOP_MAIN.getName()))
            path = desktopMainHisFile;
        else if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_MOBILE_LOGIN.getName()))
            path = mobileLoginHisFile;
        else if (templateType.getName().equals(TemplateType.TEMPLATE_TYPE_MOBILE_MAIN.getName()))
            path = mobileMainHisFile;
        FileUtil.mkdirForNoExists(StudioApp.getServletContext().getRealPath(path));
        return path;
    }

    public TemplateVo getTemplateVoBackups(TemplateType type) {
        String fileStr = StudioApp.getServletContext().getRealPath(getCoreFilePath(type) + "/META-INF/MANIFEST.MF");
        if (!new File(fileStr).exists()) {
            WebUtils.showError(Labels.getLabel("editor.template.error.choose"));
            return null;
        }
        Properties prop = new Properties();
        try {
            prop.load(new InputStreamReader(new FileInputStream(fileStr),"utf-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        TemplateVo templateVo = new TemplateVo();
        templateVo.setProductDisplayName(prop.getProperty("Template-Title"));
        templateVo.setProductType(typeString(prop.getProperty("Template-Type")));
        ArrayList<String> list = new ArrayList<>();
        list.add(prop.getProperty("Template-File"));
        templateVo.setZULFiles(list);
        return templateVo;
    }
}
